﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CSharpPaint.DrawComponents;

namespace CSharpPaint
{
    public enum DrawableTool
    {
        None,
        Line,
        Triangle,
        Square,
        Retangle,
        Eraser
    }

    public partial class MainForm : Form
    {
        #region Atributes
        private Color selectedColor;
        private Color gridColor;
        private Bitmap gridLayer;
        private DrawableTool selectedDrawTool;
        private bool drawing;
        private Point mouseGridPosition;
        private List<DrawableComponent> designedComponents;
        private DrawableComponent currentDrawingComponent;
        #endregion
        #region Proprieties
        public Color SelectedColor
        {
            get { return this.selectedColor; }

            set
            {
                this.selectedColor = value;
                this.selectedColorPictureBox.BackColor = value;

                this.rUpDown.Value = value.R;
                this.gUpDown.Value = value.G;
                this.bUpDown.Value = value.B;
                this.aUpDown.Value = value.A;
            }
        }
        #endregion

        public MainForm()
        {
            InitializeComponent();
            InitializePaintGUIComponents();
        }

        private void InitializePaintGUIComponents()
        {
            SelectedColor = Color.Black;
            this.editorWSizeUpDown.Value = this.editorBox.Width;
            this.editorHSizeUpDown.Value = this.editorBox.Height;

            this.gridColor = Color.Gray;
            this.selectedDrawTool = DrawableTool.None;
            this.drawing = false;
            this.designedComponents = new List<DrawableComponent>();

            this.mouseGridPosition = new Point(0, 0);            
        }

        private void DrawGrid()
        {
            int gridSize = (int) this.gridSizeNumericUpDown.Value;
            this.gridLayer = new Bitmap(this.editorBox.Width, this.editorBox.Height);

            using (Graphics graphics = Graphics.FromImage(this.gridLayer))
            {
                SolidBrush brush = new SolidBrush(this.gridColor);

                for (int x = -1; x < this.gridLayer.Width; x += gridSize)
                {
                    graphics.FillRectangle(brush, x, 0, 1, this.gridLayer.Height);
                }

                for (int y = -1; y < this.gridLayer.Height; y += gridSize)
                {
                    graphics.FillRectangle(brush, 0, y, this.gridLayer.Width, 1);
                }

                brush.Dispose();

            }

            JoinEditorLayers();
        }

        private void JoinEditorLayers()
        {
            if(this.gridCheckBox.Checked)
                this.editorBox.Image = new Bitmap(this.gridLayer);
            else
                this.editorBox.Image = new Bitmap(this.editorBox.Width, this.editorBox.Height);

            Bitmap components = new Bitmap(this.editorBox.Image);
                        

            using (Graphics graphics = Graphics.FromImage(this.editorBox.Image))
            {
                //graphics.DrawImage(components, 0, 0);
                foreach (DrawableComponent dc in this.designedComponents)
                {
                    SolidBrush brush = new SolidBrush(dc.Color);
                    foreach (Dot p in dc.Pixels)
                    {
                        graphics.FillRectangle(brush, 
                            p.X * (int)this.gridSizeNumericUpDown.Value,
                            p.Y * (int)this.gridSizeNumericUpDown.Value, 
                            (int)this.gridSizeNumericUpDown.Value,
                            (int)this.gridSizeNumericUpDown.Value);
                    }
                    brush.Dispose();
                }
            }
        }

        private void colorMapPictureBox_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left) 
            {
                Bitmap aux = (Bitmap)this.colorMapPictureBox.Image;
                SelectedColor = aux.GetPixel(e.Location.X, e.Location.Y);
            }            
        }
        

        private void rUpDown_ValueChanged(object sender, EventArgs e)
        {
            this.rTrackBar.Value = (int)rUpDown.Value;
            SelectedColor = Color.FromArgb((int)rUpDown.Value,
                                          this.selectedColor.G,
                                          this.selectedColor.B);
        }

        private void gUpDown_ValueChanged(object sender, EventArgs e)
        {
            this.gTrackBar.Value = (int)gUpDown.Value;
            SelectedColor = Color.FromArgb(this.selectedColor.R,
                                           (int)gUpDown.Value,
                                           this.selectedColor.B);
        }

        private void bUpDown_ValueChanged(object sender, EventArgs e)
        {
            this.bTrackBar.Value = (int)bUpDown.Value;
            SelectedColor = Color.FromArgb(this.selectedColor.R,
                                           this.selectedColor.G,
                                           (int)bUpDown.Value);
        }

        private void aUpDown_ValueChanged(object sender, EventArgs e)
        {
            this.aTrackBar.Value = (int)aUpDown.Value;
            SelectedColor = Color.FromArgb((int)aUpDown.Value, this.selectedColor);
        }

        private void rTrackBar_Scroll(object sender, EventArgs e)
        {
            rUpDown.Value = this.rTrackBar.Value;
        }

        private void gTrackBar_Scroll(object sender, EventArgs e)
        {
            gUpDown.Value = this.gTrackBar.Value;
        }

        private void bTrackBar_Scroll(object sender, EventArgs e)
        {
            bUpDown.Value = this.bTrackBar.Value;
        }

        private void aTrackBar_Scroll(object sender, EventArgs e)
        {
            aUpDown.Value = this.aTrackBar.Value;
        }

        private void mnuExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void gridCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            this.gridSizeNumericUpDown.Enabled = this.gridCheckBox.Checked;
            if (this.gridCheckBox.Checked)
                DrawGrid();
        }

        private void editorWSizeUpDown_ValueChanged(object sender, EventArgs e)
        {
            this.editorBox.Width = (int)this.editorWSizeUpDown.Value;
            //if (this.gridCheckBox.Checked)
                //DrawGrid();
        }

        private void editorHSizeUpDown_ValueChanged(object sender, EventArgs e)
        {
            this.editorBox.Height = (int)this.editorHSizeUpDown.Value;
            //if (this.gridCheckBox.Checked)
              //  DrawGrid();
        }

        private void MainForm_Resize(object sender, EventArgs e)
        {
            this.topOptionPanel.Width = this.Width - this.topOptionPanel.Left - 30;
            this.brushColorPanel.Left = this.Width - this.brushColorPanel.Width - 30;
            this.editorPanel.Width = this.brushColorPanel.Left - this.editorPanel.Left - 10;
            
            this.proprietiesGroupBox.Left = this.brushColorPanel.Left;
            this.proprietiesGroupBox.Height = this.Height - this.proprietiesGroupBox.Top - 70;
            this.editorPanel.Height = this.Height - this.editorPanel.Top - 70;
            this.editorBox.Width = this.editorPanel.Width - 5;
            this.editorWSizeUpDown.Value = this.editorBox.Width;
            this.editorBox.Height = this.editorPanel.Height - 5;
            this.editorHSizeUpDown.Value = this.editorBox.Height;

            if (gridCheckBox.Checked)
                DrawGrid();
        }

        private void gridSizeNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            DrawGrid();
        }

        private void editorBox_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (!this.drawing)
                {
                    this.drawing = true;
                    this.currentDrawingComponent = new Line(this.mouseGridPosition.X, this.mouseGridPosition.Y,
                        this.selectedColor);
                }
                else this.drawing = false;
            }
        }

        private void editorBox_MouseMove(object sender, MouseEventArgs e)
        {
            this.mouseGridPosition.X = (int)(e.X / gridSizeNumericUpDown.Value);
            this.mouseGridPosition.Y = (int)(e.Y / gridSizeNumericUpDown.Value);


            this.mousePositionLabel.Text = "X: " + this.mouseGridPosition.X +
                                         "  Y: " + this.mouseGridPosition.Y;

            if (this.drawing)
            {
                this.currentDrawingComponent.DrawLastDot(this.mouseGridPosition.X, this.mouseGridPosition.Y);
                AddNewLine();
            }
        }

        private void editorBox_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && this.drawing)
            {

                this.currentDrawingComponent.DrawLastDot(this.mouseGridPosition.X, this.mouseGridPosition.Y);
                /*
                this.drawing = false;
                this.x2 = e.X;
                this.y2 = e.Y;

                if (this.x2 < 0)
                    this.x2 = 0;
                if (this.y2 < 0)
                    this.y2 = 0;

                if (this.x2 > this.editorBox.Width)
                    this.x2 = editorBox.Width - 1;
                if (this.y2 > this.editorBox.Height)
                    this.y2 = editorBox.Height - 1;*/

                AddNewLine();                
            }

        }

        private void AddNewLine()
        {
            this.designedComponents.Add(currentDrawingComponent);
            JoinEditorLayers();
        }

        private void lineToolStripButton_Click(object sender, EventArgs e)
        {
            this.selectedDrawTool = DrawableTool.Line;
        }

        

        
    }
}
